<?php


namespace App\Common\Libs;

class WeChat
{
    private static $_weChat;

    private $_appId;
    private $_appSecret;
    private $_redirectUri;
    private $_sessionKey;

    public static function getInstance($sessionKey = null, $config = []): self
    {
        $config = $config ?: config('wechat');
        if (self::$_weChat === null) {
            self::$_weChat = new self();
        }

        self::$_weChat->_appId = $config['appId'];
        self::$_weChat->_appSecret = $config['appSecret'];
        self::$_weChat->_redirectUri = $config['redirectUrl'];
        self::$_weChat->_sessionKey = $sessionKey;

        return self::$_weChat;
    }


    // 获取微信授权链接
    public function getAuthorizeUrl($state): string
    {
        $redirectUrl = urlencode($this->_redirectUri);
        return "https://open.weixin.qq.com/connect/qrconnect?appid={$this->_appId}&redirect_uri={$redirectUrl}&response_type=code&scope=snsapi_login&state={$state}#wechat_redirect";
    }

    // 获取授权token
    public function getAccessToken($code)
    {
        $tokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";

        try {
            return HttpClient::getInstance()->get($tokenUrl, [
                'appid' => $this->_appId,
                'secret' => $this->_appSecret,
                'code' => $code,
                'grant_type' => 'authorization_code'
            ]);
        } catch (\JsonSchema\Exception\InvalidConfigException $e) {
            return false;
        } catch (\Exception $e) {
            return false;
        }

    }

    // 获取授权后的微信用户信息
    public function getUserAuthInfoByCode($code)
    {
        $data = $this->getAccessToken($code);
        if ($data['access_token'] && $data['openid']) {
            $infoUrl = "https://api.weixin.qq.com/sns/userinfo";

            try {
                return HttpClient::getInstance()->get($infoUrl, [
                    'access_token' => $data['access_token'],
                    'openid' => $data['openid'],
                    'lang' => 'zh_CN'
                ]);
            } catch (\Exception $e) {
                return false;
            }
        }
    }

    /**
     * 检验数据的真实性，并且获取解密后的明文.
     * @param $encryptedData string 加密的用户数据
     * @param $iv string 与用户数据一同返回的初始向量
     * @param $data string 解密后的原文
     *
     * @return int 成功0，失败返回对应的错误码
     */
    public function decryptData($encryptedData, $iv)
    {
        if (strlen($this->_sessionKey) !== 24) {
            return false;
        }
        $aesKey = base64_decode($this->_sessionKey);


        if (strlen($iv) !== 24) {
            return false;
        }
        $aesIV = base64_decode($iv);

        $aesCipher = base64_decode($encryptedData);

        $result = openssl_decrypt($aesCipher, 'AES-128-CBC', $aesKey, 1, $aesIV);

        $dataObj = json_decode($result, true);
        if ($dataObj === null) {
            return false;
        }
        $appid = config('wechat')['appId'];
        if ($dataObj['watermark']['appid'] != $appid) {
            return false;
        }
        return $result;
    }
}
